/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servlet;

import BusinessLogic.Constants;
import BusinessLogic.PartnerBeanLocal;
import EntityState.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 *
 * @author James
 */
public class PartnerServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @EJB
    private PartnerBeanLocal partnerBean;
    
    private ArrayList data = null;
    private List<PartnerPrivilegeState> fullListOfPrivileges;
    
    @Override
    public void init() {
        System.out.println("PartnerServlet: init()");
        //fullListOfPrivileges = partnerBean.getFullListOfPrivileges();
    }
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        RequestDispatcher dispatcher;
        ServletContext servletContext = getServletContext();

        String page = request.getPathInfo();
        page        = page.substring(1);
        System.out.println("PartnerServlet: " + page);
        
        if (page.equals("") || page.equals("index")) {
            //nothing to do
            page = "index";
            
        } else if (page.equals("AddItem")) {
            //nothing to do
            
        } else if (page.equals("AddItemStatus")) {
            data = addItem(request);
            request.setAttribute("data", data);
            
        }
        
        if ((dispatcher = servletContext.getNamedDispatcher(page)) == null) dispatcher = servletContext.getNamedDispatcher("Error");
        else dispatcher.forward(request, response);
    }
    
    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
    private ArrayList getPartnerProfile(HttpServletRequest request) {
        ArrayList list = new ArrayList();
        
        PartnerAccountState pas = isSessionExpired(request);
        if (pas == null) list.add(Constants.STATUS_SESSION_EXPIRED);
        else if (!partnerBean.checkPrivilege(pas.getUsername(), Constants.PARTNER_CHANGE_PARTNER_PROFILE)) list.add(Constants.STATUS_NOT_ALLOWED);
        else {
            String partnerID = request.getParameter("partnerID");
            if (partnerID == null) list.add(Constants.STATUS_INVALID_INPUT);
            else list = partnerBean.getInfo(Constants.GET_PARTNER_PROFILE, Long.parseLong(partnerID));
        }
        
        return list;
    }
    
    private ArrayList addReservableUnit(HttpServletRequest request) {
        ArrayList list = new ArrayList();
        
        PartnerAccountState pas = isSessionExpired(request);
        if (pas == null) list.add(Constants.STATUS_SESSION_EXPIRED);
        else if (!partnerBean.checkPrivilege(pas.getUsername(), Constants.PARTNER_CHANGE_PARTNER_PROFILE)) list.add(Constants.STATUS_NOT_ALLOWED);
        else {
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (isMultipart) {
                try {
                    String name, description, numOfCustomersPerUnit, numOfAvailableUnits, itemID, outletID;
                    // Get necessary information
                    HashMap compulsory = Utility.getCompulsoryMultipartFormFieldParameters(request, "name", "numOfCustomersPerUnit", "numOfAvailableUnits", "outletID");
                    HashMap optional   = Utility.getOptionalMultipartFormFieldParameters(request, "description", "itemID");
                    HashMap pictures   = Utility.getMultipartFileParametersWithPrefix(request, "picture");
                    HashMap pictDescriptions = Utility.getMultipartFormFieldParametersWithPrefix(request, "description");
                    if (compulsory.isEmpty() || pictures.size() > Constants.FILE_MAX_NUM_OF_RESERVABLE_UNIT_PICTURE || pictures.size() != pictDescriptions.size()) list.add(Constants.STATUS_INVALID_INPUT);
                    else {
                        name                  = (String) compulsory.get("name");
                        description           = (String) optional.get("description");
                        numOfCustomersPerUnit = (String) compulsory.get("numOfCustomersPerUnit");
                        numOfAvailableUnits   = (String) compulsory.get("numOfAvailableUnits");
                        itemID                = (String) optional.get("itemID");
                        outletID              = (String) compulsory.get("outletID");
                        FileItem layout       = (FileItem) Utility.getOptionalMultipartFileParameters(request, "layout").get("layout");
                        if (itemID.equals("")) list.add(partnerBean.addReservableUnit(name, description, Integer.parseInt(numOfCustomersPerUnit), Integer.parseInt(numOfAvailableUnits), 0, Long.parseLong(outletID), pictures, pictDescriptions, layout));
                        else list.add(partnerBean.addReservableUnit(name, description, Integer.parseInt(numOfCustomersPerUnit), Integer.parseInt(numOfAvailableUnits), Long.parseLong(itemID), Long.parseLong(outletID), pictures, pictDescriptions, layout));
                    }
                } catch (Exception ex) {
                    list.add(Constants.STATUS_UNEXPECTED_ERROR);
                    Logger.getLogger(PartnerServlet.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else list.add(Constants.STATUS_INVALID_INPUT);
        }
        
        return list;
    }
    
    private ArrayList addOutlet(HttpServletRequest request) {
        ArrayList list = new ArrayList();
        
        PartnerAccountState pas = isSessionExpired(request);
        if (pas == null) list.add(Constants.STATUS_SESSION_EXPIRED);
        else if (!partnerBean.checkPrivilege(pas.getUsername(), Constants.PARTNER_CHANGE_PARTNER_PROFILE)) list.add(Constants.STATUS_NOT_ALLOWED);
        else {
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (isMultipart) {
                try {
                    String name, address1, address2, postalCode, countryCode, phone, country, province, city, businessEmail;
                    // Get necessary information
                    HashMap compulsory       = Utility.getCompulsoryMultipartFormFieldParameters(request, "name", "address1", "address2", "postalCode", "countryCode", "phone", "country", "businessEmail");
                    HashMap optional         = Utility.getOptionalMultipartFormFieldParameters(request, "address2", "province", "city");
                    HashMap pictures         = Utility.getMultipartFileParametersWithPrefix(request, "picture");
                    HashMap pictDescriptions = Utility.getMultipartFormFieldParametersWithPrefix(request, "description");
                    if (compulsory.isEmpty() || pictures.isEmpty() || pictures.size() > Constants.FILE_MAX_NUM_OF_OUTLET_PICTURE || pictures.size() != pictDescriptions.size()) list.add(Constants.STATUS_INVALID_INPUT);
                    else {
                        name            = (String) compulsory.get("name");
                        address1        = (String) compulsory.get("address1");
                        address2        = (String) optional.get("address2");
                        postalCode      = (String) compulsory.get("postalCode");
                        countryCode     = (String) compulsory.get("countryCode");
                        phone           = (String) compulsory.get("phone");
                        country         = (String) compulsory.get("country");
                        province        = (String) optional.get("province");
                        city            = (String) optional.get("city");
                        businessEmail   = (String) compulsory.get("businessEmail");
                        FileItem layout = (FileItem) Utility.getOptionalMultipartFileParameters(request, "layout").get("layout");
                        list.add(partnerBean.addOutlet(name, address1, address2, postalCode, countryCode, phone, country, province, city, businessEmail, pas.getPartner().getId(), pictures, pictDescriptions, layout));
                    }
                } catch (Exception ex) {
                    list.add(Constants.STATUS_UNEXPECTED_ERROR);
                    Logger.getLogger(PartnerServlet.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else list.add(Constants.STATUS_INVALID_INPUT);
        }
        
        return list;
    }
    
    private ArrayList addItemCategory(HttpServletRequest request) {
        ArrayList list = new ArrayList();
        
        PartnerAccountState pas = isSessionExpired(request);
        if (pas == null) list.add(Constants.STATUS_SESSION_EXPIRED);
        else if (!partnerBean.checkPrivilege(pas.getUsername(), Constants.PARTNER_CHANGE_PARTNER_PROFILE)) list.add(Constants.STATUS_NOT_ALLOWED);
        else {
            String name, description, outletID;
            // Get necessary information
            HashMap compulsoryPara = Utility.getCompulsoryParameters(request, "name");
            HashMap optionalPara   = Utility.getOptionalParameters(request, "description", "outletID");
            if (compulsoryPara.isEmpty()) list.add(Constants.STATUS_INVALID_INPUT);
            else {
                // partnerID or outletID must be available
                name        = (String) compulsoryPara.get("name");
                description = (String) optionalPara.get("description");
                outletID    = (String) optionalPara.get("outletID");
                if (outletID.equals("")) list.add(partnerBean.addItemCategory(name, description, pas.getPartner().getId(), 0)); 
                else list.add(partnerBean.addItemCategory(name, description, 0, Long.parseLong(outletID)));
            }
        }
        
        return list;
    }
    
    private ArrayList addItem(HttpServletRequest request) {
        ArrayList list = new ArrayList();
        
        PartnerAccountState pas = isSessionExpired(request);
        if (pas == null) list.add(Constants.STATUS_SESSION_EXPIRED);
        else if (!partnerBean.checkPrivilege(pas.getUsername(), Constants.PARTNER_CHANGE_PARTNER_PROFILE)) list.add(Constants.STATUS_NOT_ALLOWED);
        else {
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (isMultipart) {
                try {
                    // Get necessary information
                    HashMap compulsory       = Utility.getCompulsoryMultipartFormFieldParameters(request, "name", "categoryID", "description", "type", "discount", "price", "redeemPrice", "additionalLoyaltyPoint", "selling");
                    HashMap pictures         = Utility.getAllMultipartFileParameters(request);
                    HashMap pictDescriptions = Utility.getMultipartFormFieldParametersWithPrefix(request, "description");
                    if (compulsory.isEmpty() || pictures.isEmpty() || pictures.size() > Constants.FILE_MAX_NUM_OF_ITEM_PICTURE || pictures.size() != pictDescriptions.size()) {
                        list.add(Constants.STATUS_INVALID_INPUT);
                        return list;
                    } else {
                        // Get the form field information:
                        String name, categoryID, description, type, discount, price, redeemPrice, additionalLoyaltyPoint, selling;
                        name        = (String) compulsory.get("name");
                        categoryID  = (String) compulsory.get("categoryID");
                        description = (String) compulsory.get("decription");
                        type        = (String) compulsory.get("type");
                        discount    = (String) compulsory.get("discount");
                        price       = (String) compulsory.get("price");
                        redeemPrice = (String) compulsory.get("redeemPrice");
                        selling     = (String) compulsory.get("selling");
                        additionalLoyaltyPoint = (String) compulsory.get("additionalLoyaltyPoint");
                        
                        // Get the IDs of sub items:
                        String[] subItems = Utility.getMultipartFormFieldParameterValues(request, "subItem");
                        long[] listOfSubItems = null;
                        if (subItems.length != 0) {
                            listOfSubItems     = new long[subItems.length];
                            for (int i = 0 ; i < subItems.length ; i++) {
                                listOfSubItems[i] = Long.parseLong(subItems[i]);
                            }
                        }
                        
                        // Call the bean to create the item
                        if (selling.equals("1")) list.add(partnerBean.addItem(name, description, pictures, pictDescriptions, Integer.parseInt(type), Integer.parseInt(discount), Integer.parseInt(price), Integer.parseInt(redeemPrice), Integer.parseInt(additionalLoyaltyPoint), true, listOfSubItems, Long.parseLong(categoryID)));
                        else list.add(partnerBean.addItem(name, description, pictures, pictDescriptions, Integer.parseInt(type), Integer.parseInt(discount), Integer.parseInt(price), Integer.parseInt(redeemPrice), Integer.parseInt(additionalLoyaltyPoint), false, listOfSubItems, Long.parseLong(categoryID)));
                    }
                } catch (Exception ex) {
                    list.add(Constants.STATUS_UNEXPECTED_ERROR);
                    Logger.getLogger(PartnerServlet.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else list.add(Constants.STATUS_INVALID_INPUT);
        }
        
        return list;
    }
    
    private ArrayList login(HttpServletRequest request) {
        ArrayList list = new ArrayList();
        PartnerAccountState pas;

        //Check if user has logined recently
        if ((pas = isSessionExpired(request)) != null) {
            //Show him the user control panel 
            list.add(Constants.STATUS_SUCCESSFUL);
            list.add(pas.getUsername());
        } else {
            //If new user, try to get the Username and Password
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            String timezone = request.getParameter("timezone");

            //If no Username was submitted, this is a new user
            if (username == null) list.add(Constants.STATUS_NEW_SESSION);
            else {
                //If a Username was submitted, look for an entry in the database
                pas = partnerBean.login(username, password, timezone);
                if (pas == null) list.add(Constants.STATUS_WRONG_PASSWORD); //Wrong Username or Password
                else if (pas.isActivated() && pas.isActive()) { //If this user exitst, check if he activated his account
                    list.add(Constants.STATUS_SUCCESSFUL);
                    HttpSession clientSession = request.getSession();
                    clientSession.setMaxInactiveInterval(1800);
                    clientSession.setAttribute("partner", pas);
                    clientSession.setMaxInactiveInterval(86400);
                } else {
                    if (!pas.isActivated()) list.add(Constants.STATUS_USER_INACTIVATED);
                    else if (!pas.isActive()) list.add(Constants.STATUS_ACCOUNT_BANNED);
                    list.add(username);
                }
            }
        }
        
        return list;
    }
    //Utility function:
    private PartnerAccountState isSessionExpired(HttpServletRequest request) {
        HttpSession partnerSession = request.getSession(false);
        PartnerAccountState pas;
        if (partnerSession == null || (pas = (PartnerAccountState) partnerSession.getAttribute("partner")) == null) return null;
        else return pas; 
    }
}
